Skip to content

Stage 2: described runs write manifest version "4" - #227

Merged
guijacquemet merged 2 commits into
mainfrom
claude/manifest-v4-described
Nov 8, 2026
Merged

guijacquemet merged 2 commits into
mainfrom
claude/manifest-v4-described

Conversation

@guijacquemet

@guijacquemet guijacquemet commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

What

A run manifest that carries experiment_description now has manifest_version "4". Undescribed runs keep "2" or "3" byte for byte.

  • read_manifest and RunInputs.open read version 4.
  • A version 4 manifest without experiment_description is refused, and so is a version 1, 2 or 3 manifest with one. The writer and the reader share check_version.
  • Version 4 keeps the content rule of 2 and 3: a content_sha256 in every entry exactly when settings.verify_content is true.
  • Contract §9 (manifest_version row) and the CHANGELOG are updated.

Why

Stage 2 design, question 9, owner answer 9 (2026-11-08): a v0.4.0 reader skips keys it does not know (manifest.py:357-412), so it opened a described run and ignored the description. It would name channels by header, pair by folder name and never check masks. Older readers refuse an unknown version, so they now refuse described runs. This must land before the v0.5.0 tag.

Regression evidence

New tests/test_described_manifest_version.py (10 tests):

  • A described run writes "4" (with and without verify_content) and reads back through read_manifest and RunInputs.open.
  • An older-reader simulation runs the code of the v0.4.0 tag through tests/released_code.py. It refuses the "4" manifest with Manifest version '4' is not supported, and still reads an undescribed manifest.
  • The mismatched combinations are refused: version 4 without a description, and versions 1, 2 and 3 with one.
  • Undescribed runs keep "2" or "3".

On main (source reverted, tests kept): 8 failed, 2 passed. The 2 that pass are the "undescribed run keeps its version" cases, which are expected to pass on both sides. With the change: 10 passed.

tests/test_strict_manifest.py used "4" as its "unknown later version". It now uses "5", and the expected message lists '1', '2', '3', '4'.

Checks

python tools/check.py: ruff check and format clean, 4585 passed, 4 skipped, code rules clean. The 4 skips are environmental: 3 need a case-sensitive-name file system check (test_cli_log.py:165, test_folder_rules.py:201 and :229) and 1 needs file modes to apply (test_discovery.py:665, running as root). The v0.4.0 parity suite tests/test_parity_v0_4_0.py passes unchanged. manifest.py is 599 lines (limit 600).

Needs an owner decision

🤖 Generated with Claude Code

https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm

A v0.4.0 reader skips keys it does not know, so it opened a run with an
experiment_description and silently ignored it (Stage 2 design question 9,
owner answer 9). A run manifest that carries experiment_description now has
manifest_version "4"; undescribed runs keep "2" or "3" byte for byte.
read_manifest and RunInputs.open read version 4 and refuse a mismatch in
either direction (reader and writer share check_version).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
@guijacquemet
guijacquemet merged commit ef05175 into main Nov 8, 2026
7 checks passed
@guijacquemet
guijacquemet deleted the claude/manifest-v4-described branch November 8, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants